import os
from pathlib import Path
from conf.env import *

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = 'django-insecure--)gt==!5lm=a2hoe!)qkrvj8j$n2pcn(oos+6xk)%-%d4%^t#hqmv'

DEBUG = True
AUTH_USER_MODEL = 'User.User'

# =============== #
# **  解决跨域  ** #
# =============== #

ALLOWED_HOSTS = ALLOWED_HOSTS
# 允许跨域源
CORS_ORIGIN_ALLOW_ALL = CORS_ORIGIN_ALLOW_ALL
# 允许ajax请求携带cookie
CORS_ALLOW_CREDENTIALS = CORS_ALLOW_CREDENTIALS
X_FRAME_OPTIONS = "ALLOW-FROM"

CORS_ORIGIN_WHITELIST = ()

# 定义允许请求的方式
CORS_ALLOW_METHODS = (
    'DELETE', 'GET', 'OPTIONS', 'PATCH',
    'POST', 'PUT', 'VIEW',)

# CORS_ALLOW_HEADERS 定义请求头的字段
CORS_ALLOW_HEADERS = (
    'XMLHttpRequest',
    'X_FILENAME',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'Pragma',
    'token')

# X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在 <frame>, </iframe> 或者 <object> 中展现的标记。网站可以使用此功能，
# 来确保自己网站的内容没有被嵌套到别人的网站中去，也从而避免了点击劫持 (clickjacking) 的攻击。

# X-Frame-Options三个参数:
# 1、DENY
# 表示该页面不允许在frame中展示，即便是在相同域名的页面中嵌套也不允许。
# 2、SAMEORIGIN
# 表示该页面可以在相同域名页面的frame中展示。
# 3、ALLOW-FROM uri
# 表示该页面可以在指定来源的frame中展示。

# Application definition

INSTALLED_APPS = [
    'corsheaders',  # 解决跨域的问题
    'daphne',  # 后续版本中channels直接安装这个就行了
    # 'channels', # 4版本不用注册该APP
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'captcha',  # 验证码
    'drf_yasg',  # swagger
    'django_celery_beat',
    'django_filters',

    'Apps.Home',
    'Apps.Demo',
    'Apps.User',
    'Apps.System',
    'Apps.Project',
    'Apps.UiTest',
    'Apps.Interface'

]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # 解决跨域问题，中间件
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'Main.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# =================== #
# **  启动服务器选择  ** #
# =================== #

# WSGI_APPLICATION = 'Main.wsgi.application'
ASGI_APPLICATION = 'Main.asgi.application'

# ========================= #
# ** channel_layers 配置  ** #
# ========================= #

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("127.0.0.1", 6379)],
        },
    },
}

# ================= #
# **  数据库 配置  ** #
# ================= #
# Database
REDIS_ENABLE = True

if DATABASE_TYPE == "MYSQL":
    # Mysql数据库
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",
            "HOST": os.getenv('DATABASE_HOST') or DATABASE_HOST,
            "PORT": DATABASE_PORT,
            "USER": DATABASE_USER,
            "PASSWORD": DATABASE_PASSWORD,
            "NAME": DATABASE_NAME,
        }
    }
else:
    # sqlite3 数据库
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }

"""
3.8.0 开始，URL格式
redis://[:password]@localhost:6379/0
rediss://[:password]@localhost:6379/0
unix://[:password]@/path/to/socket.sock?db=0
"""

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": f"redis://{REDIS}:6379/1",
        'TIMEOUT': 300,  # 缓存超时时间(默认为300秒,None表示永不过期)
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

# Django默认的Session是存储在sql数据库里的，但我们都知道普通的数据会被数据存储在硬盘上，速度没有那么快，
# 如果想改成存储在redis里，只需要在配置文件里配置一下就行
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
# DJANGO_REDIS_IGNORE_EXCEPTIONS = True

# channels 配置redis
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [(REDIS, 6379)],
        },
    },
}

# Password validation

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-Hans'

LOCALE_PATHS = [
    BASE_DIR / "locale",
]

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

# USE_TZ = True
USE_TZ = False

# =================== #
# **  静态文件 配置  ** #
# =================== #

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATIC_URL = 'static/'
# # 设置django的静态文件目录
STATICFILES_DIRS = [(os.path.join(BASE_DIR, "static"))]

if not os.path.exists(os.path.join(BASE_DIR, 'media')):
    os.makedirs(os.path.join(BASE_DIR, 'media'))
# 访问上传文件的url地址前缀
MEDIA_URL = "/media/"
# 项目中存储上传文件的根目录
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# ========================= #
# **  restFramework 配置  ** #
# ========================= #

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'Apps.util.jwt_util.JwtTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',  # 基础认证
        # 'rest_framework.authentication.TokenAuthentication',  # token认证

    ),
    'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S",  # 日期时间格式配置
    'DATE_FORMAT': "%Y-%m-%d",
    'EXCEPTION_HANDLER': 'Apps.common.exc_response.CustomExceptionHandler',
    'DEFAULT_PAGINATION_CLASS': 'Apps.common.pagination.CustomPagination',  # 自定义分页
    'DEFAULT_FILTER_BACKENDS': ("django_filters.rest_framework.DjangoFilterBackend",)
}
JWT_TOKEN_TIMEOUT = 60 * 60 * 20  # 单位:秒
#
# # =================== #
# # **  SWAGGER 配置  ** #
# # =================== #
#
SWAGGER_SETTINGS = {
    'LOGIN_URL': '/admin/login',
    'LOGOUT_URL': '/admin/logout',
    'PERSIST_AUTH': True,
    'REFETCH_SCHEMA_WITH_AUTH': True,
    'REFETCH_SCHEMA_ON_LOGOUT': True,

    # 接口文档中方法列表以首字母升序排列
    'APIS_SORTER': 'alpha',
    # 如果支持json提交, 则接口文档中包含json输入框
    'JSON_EDITOR': True,
    # 方法列表字母排序
    'OPERATIONS_SORTER': 'alpha',

    'DEFAULT_INFO': 'Main.urls.swagger_info',  # 这里注意，更改为自己的项目路径

    # 基础样式
    'SECURITY_DEFINITIONS': {
        'Basic': {
            'type': 'basic'
        },
        'Bearer': {
            'type': 'apiKey',
            'name': 'authorization',
            'in': 'header'
        },
        'Query': {
            'type': 'apiKey',
            'name': 'auth',
            'in': 'query'
        }
    }
}

# =================== #
# **  验证码   配置  ** #
# =================== #
# 设置 captcha 是否可用，如果为False，则不校验验证码
CAPTCHA_STATE = True
# 设置 captcha 图片大小
CAPTCHA_IMAGE_SIZE = (160, 60)
# 设置字符个数
CAPTCHA_LENGTH = 4
# 超时（分钟）
CAPTCHA_TIMEOUT = 1
CAPTCHA_OUTPUT_FORMAT = '%(images)s %(text_field)s %(hidden_filed)s'
# 字体大小
CAPTCHA_FONT_SIZE = 40
# 前景色
CAPTCHA_FOREGROUND_COLOR = '#0033FF'
# 背景色
CAPTCHA_BACKGROUND_COLOR = '#F5F7F4'

CAPTCHA_NOISE_FUNCTIONS = ("captcha.helpers.noise_arcs", "captcha.helpers.noise_dots")
# 字母验证码（默认）
# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
# 加减乘除验证码
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'

# # =================== #
# # **  log日志 配置  ** #
# # =================== #
#
# # log 配置部分BEGIN #
SERVER_LOGS_FILE = os.path.join(BASE_DIR, 'logs', 'server.log')
ERROR_LOGS_FILE = os.path.join(BASE_DIR, 'logs', 'error.log')
if not os.path.exists(os.path.join(BASE_DIR, 'logs')):
    os.makedirs(os.path.join(BASE_DIR, 'logs'))

# 格式:[INFO][2020-04-22 23:33:01][Application_backend.apps.ready():16]  这是一条日志:
# 格式:[级别][日期][logger-模块.函数名称():行号]  信息
# [INFO] [2021-12-26 16:16:24][django.server.log_message():179] "GET /login/ HTTP/1.1" 200 4
STANDARD_LOG_FORMAT = '[%(levelname)s][%(asctime)s][%(name)s-%(module)s.%(funcName)s():%(lineno)d]%(message)s'
CONSOLE_LOG_FORMAT = '[%(levelname)s][%(asctime)s][%(name)s-%(module)s.%(funcName)s():%(lineno)d]%(message)s'

# 日志
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,  # 是否禁用已经存在的日志器
    'formatters': {  # 日志信息显示的格式
        'standard': {
            'format': STANDARD_LOG_FORMAT,
            'datefmt': '%Y-%m-%d %H:%M:%S',
        },
        'console': {
            'format': CONSOLE_LOG_FORMAT,
            'datefmt': '%Y-%m-%d %H:%M:%S',
        },
    },
    'handlers': {  # 日志处理方法
        'console': {  # 向终端中输出日志
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'console'
        },
        'error': {
            'level': 'ERROR',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': ERROR_LOGS_FILE,
            'maxBytes': 1024 * 1024 * 100,  # 100 MB
            'backupCount': 3,  # 最多备份3个
            'formatter': 'standard',
            'encoding': 'utf-8',
        },
        'file': {  # 向文件中输出日志
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': SERVER_LOGS_FILE,  # 日志文件的位置
            'maxBytes': 1024 * 1024 * 100,  # 100M
            'backupCount': 5,  # 最多备份5个
            'formatter': 'standard'
        },
    },
    'loggers': {  # 日志器
        'django': {  # 定义了一个名为django的日志器,
            'handlers': ['console', 'error', 'file'],  # 可以同时向终端与文件中输出日志
            'propagate': True,  # 是否继续传递日志信息
            'level': 'INFO',  # 日志器接收的最低日志级别
        },
    }
}
#
# # =================== #
# # **  邮件 配置  ** #
# # =================== #
#
# EMAIL_HOST = EMAIL_HOST
# EMAIL_PORT = EMAIL_PORT
# EMAIL_HOST_USER = EMAIL_HOST_USER
# EMAIL_HOST_PASSWORD = EMAIL_HOST_PASSWORD
# EMAIL_USE_LOCALTIME = False
# EMAIL_TIMEOUT = None
#
# # =================== #
# # **  CELERY 配置  ** #
# # =================== #

# Celery Configuration Options
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60
CELERY_BROKER_URL = f'redis://{REDIS}:6379/14'
CELERY_RESULT_BACKEND = f'redis://{REDIS}:6379/15'

# 结果序列化方案
CELERY_RESULT_SERIALIZER = 'json'

# 任务结果过期时间，秒
CELERY_TASK_RESULT_EXPIRES = 60 * 60 * 24

# 指定导入的任务模块，可以指定多个
# CELERY_IMPORTS = (
#    'other_dir.tasks',
# )


# celery beat配置
# CELERY_ENABLE_UTC = False
DJANGO_CELERY_BEAT_TZ_AWARE = False
# CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseSchedule


# # =================== #
# # **  HUB node  配置  ** #
# # =================== #
# 手动HUB服务
DRIVER_HUB = "http://124.222.146.157:4444/wd/hub"
# 自动新建节点的HUB服务
# DRIVER_HUB_AUTO = "http://192.168.24.150:4444"
